/**
* 
**/
#include <stdio.h>
#include <stdlib.h>

typedef struct _node {
  int data;
  struct _node * next; // 指向下一个
  struct _node * prev; // 指向上一个
} node;

node *create_data()
{
  int data;
  node *start = NULL;
  printf("input data (with q to end):");
  while ( 1 == scanf("%d", &data) ) { // 输入q + 回车退出
    node *p = (node *)malloc(sizeof(node));
    if (NULL == p) {
      exit(-1); // 内存都分配失败,挂了
    }
    
    p->data = data;
    
    p->next = start;
    if (NULL != start) {
      start->prev = p;
    }
    p->prev = NULL;
    
    start  = p;
  }
  
  return start;
}

// 传入2级指针因为,有可能要删除头节点
// 返回0表示成功,返回-1表示链表没有要删除的值
int del_node(node **start, int data)
{
  if (NULL != *start) {  // 链表不为空则可删除
    node *p,*q;
    p = *start; // 指向头结点
    q = p->next; // 指向下一个节点
    
    if (data == p->data) { // 要删除头结点
      *start = p->next;
      free(p);
      return 0;
    }
    
    while (q != NULL) {
      if (data == q->data) {
        p->next = q->next; // 将上一个节点和下一个节点连接
        q->next->prev = p; // 将下个节点的上个节点连接
        free(q);  // 释放本节点
        return 0;
      }
      p = p->next;
      q = q->next;
    } // end while
  } // end if 
  return -1;
}

int insert_node(node **start, int data)
{
  node *p = (node *)malloc(sizeof(node));
  if (NULL == p) {
    exit(-1); // 内存都分配失败,挂了
  }
  
  p->data = data;
  p->next = *start;
  p->prev = NULL;
  *start  = p; // 头插法插入节点
  return 0;
}

// 链表长度
int len_node(node *start)
{
  int len = 0;
  while (start != NULL) {
    start = start->next;
    len++;
  }
  return len;
}

// 打印整个链表
void print_node(node *start)
{
  while (start != NULL) {
    printf("%d,", start->data);
    start = start->next;
  }
  printf("\n");
}

int main(int argc, char *argv[])
{
  node * xxx = create_data();
  printf("len = %d\n", len_node(xxx));
  
  print_node(xxx);
  // del_node(&xxx, 3);
  // del_node(&xxx, 5);
  // print_node(xxx);
  // insert_node(&xxx, 123);
  // insert_node(&xxx, 456);
  // print_node(xxx);
  // sort_node(xxx);
  // print_node(xxx);
  // reverse_node(&xxx);
  // print_node(xxx);
  return 0;
}
